package org.microframework.cloud.gateway.config;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 本地文件路由配置加载
 * 从指定路径加载路由配置文件
 * 
 * 注意：此配置类仅在未启用Nacos配置时生效
 */
@Slf4j
@Configuration
@ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", havingValue = "false", matchIfMissing = false)
public class RouteConfiguration {

    @Value("${spring.cloud.gateway.routes-path:classpath:routes/micro-cloud-gateway-routes.json}")
    private String routesPath;

    @Bean
    public RouteDefinitionRepository fileRouteDefinitionRepository(ObjectMapper objectMapper) {
        log.info("启用本地文件路由配置: {}", routesPath);
        return new FileRouteDefinitionRepository(routesPath, objectMapper);
    }

    /**
     * 基于文件的路由定义仓库
     */
    @Slf4j
    static class FileRouteDefinitionRepository implements RouteDefinitionRepository {
        private final String routesPath;
        private final ObjectMapper objectMapper;
        private List<RouteDefinition> routeDefinitions;

        public FileRouteDefinitionRepository(String routesPath, ObjectMapper objectMapper) {
            this.routesPath = routesPath;
            this.objectMapper = objectMapper;
            this.routeDefinitions = loadRouteDefinitions();
        }

        @Override
        public Flux<RouteDefinition> getRouteDefinitions() {
            return Flux.fromIterable(this.routeDefinitions);
        }

        @Override
        public Mono<Void> save(Mono<RouteDefinition> route) {
            return Mono.empty(); // 只读实现，不支持保存
        }

        @Override
        public Mono<Void> delete(Mono<String> routeId) {
            return Mono.empty(); // 只读实现，不支持删除
        }

        /**
         * 从文件加载路由定义
         */
        private List<RouteDefinition> loadRouteDefinitions() {
            try {
                Resource resource;
                if (routesPath.startsWith("classpath:")) {
                    resource = new ClassPathResource(routesPath.substring("classpath:".length()));
                } else {
                    throw new IllegalArgumentException("不支持的路由配置路径: " + routesPath);
                }

                if (!resource.exists()) {
                    log.warn("路由配置文件不存在: {}", routesPath);
                    return new ArrayList<>();
                }

                List<RouteDefinition> definitions = objectMapper.readValue(
                        resource.getInputStream(),
                        new TypeReference<List<RouteDefinition>>() {}
                );

                log.info("成功加载{}个路由定义", definitions.size());
                definitions.forEach(route -> 
                    log.info("加载路由: id={}, uri={}, predicates={}", 
                            route.getId(), route.getUri(), route.getPredicates()));

                return definitions;
            } catch (IOException e) {
                log.error("加载路由配置文件失败: " + routesPath, e);
                return new ArrayList<>();
            }
        }
    }
} 